package com.jzg.sys.common.shiro;

import com.alibaba.fastjson.JSONObject;
import com.jzg.sys.api.base.CacheService;
import com.jzg.sys.api.sec.UserService;
import com.jzg.sys.dao.entity.SecUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
public class StatelessRealm extends AuthorizingRealm {
    @Autowired
    private CacheService cacheService;
    @Autowired
    private UserService userService;
    @Value("${cus.sysCode}")
    private String sysCode;
    @Value("${cus.timeout}")
    private int timeout;

    @Override
    public boolean supports(AuthenticationToken token) {
        // 仅支持StatelessToken类型的Token
        return token instanceof StatelessToken;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        StatelessToken statelessToken = (StatelessToken) authenticationToken;
        Object obj = cacheService.get(statelessToken.getToken(), sysCode);
        if (obj == null) {
            throw new UnauthorizedException("token过期");
        }
        //刷新token
        cacheService.put(statelessToken.getToken(), obj, sysCode, timeout*60l);
        JSONObject jsonObj = (JSONObject) obj;
        SecUser user = userService.findUserById(jsonObj.getString("userId"));
        ShiroPrincipal subject = new ShiroPrincipal(user);
        List<String> resources = userService.getResourcesCode(user.getUserId());
        List<String> roleList = userService.getRolesCode(user.getUserId());
        subject.setResources(resources);
        subject.setRoles(roleList);
        subject.setAuthorized(true);
        return new SimpleAuthenticationInfo(subject, statelessToken.getCredentials(), getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 获取当前登录的用户名
        ShiroPrincipal subject = (ShiroPrincipal) super.getAvailablePrincipal(principals);
        String username = subject.getUsername();
        String userId = subject.getId();
        try {
            if (!subject.isAuthorized()) {
                // 根据用户名称，获取该用户所有的权限列表
                List<String> authorities = userService.getResourcesCode(userId);
                List<String> roleList = userService.getRolesCode(userId);
                subject.setResources(authorities);
                subject.setRoles(roleList);
                subject.setAuthorized(true);
            }
        } catch (RuntimeException e) {
            throw new AuthorizationException("用户【" + username + "】授权失败");
        }
        // 给当前用户设置权限
        info.addStringPermissions(subject.getResources());
        info.addRoles(subject.getRoles());
        return info;
    }
}
